package org.example.cloud.payment.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
@RequestMapping("/payment2")
public class PaymentController2 {

    @Value("${server.port}")
    private Integer port;

    /**
     * 总结：服务降级，只是给个友好提示，服务被调用，依然走正常业务处理，存在雪崩风险
     * @return
     */
    //测试hytrix降级---发生降级，但是服务不会熔断，还是会继续接受请求，及其有可能会拖慢其它服务
    @HystrixCommand(fallbackMethod ="handle",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "false")})
    @GetMapping("/hytrix/ok")
    public String hytrixOk(){
        System.out.println("执行开始--hytrixOk-2");
        int i=10/0;  //演示发生异常
        //sleep();  //演示阻塞，卡顿
        System.out.println(Thread.currentThread().getName()+"--hytrixOk-2");
        System.out.println("执行结束--hytrixOk-2");
        return "ok";
    }

    private void sleep(){
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            //e.printStackTrace();
        }
    }


    //测试hytrix熔断
    /**
     * @see com.netflix.hystrix.HystrixCommandProperties
     * circuitBreaker.sleepWindowInMilliseconds 熔断休眠时间窗口（默认5000），过了休眠时间段，熔断器才会放部分流量进行真实调用，否则走fallbackMethod（不影响上游服务）
     * circuitBreaker.enabled  熔断器开关（true） 关闭后服务不会被熔断，如果服务响应慢，会导致雪崩，影响上游服务全部瘫痪
     * circuitBreaker.requestVolumeThreshold 熔断次数统计阈值（默认20），计算失败率的总数参考值
     * circuitBreaker.errorThresholdPercentage 熔断失败的百分比（默认50%），计算失败比例，达到错误比例将熔断
     *
     * 总结：
     * 1.达到熔断条件后，会拒绝访问，直接走fallback进行服务降级，不会拖垮上游服务，防止服务雪崩
     * 2.熔断有三种状态，close->open->half open->(close/open)
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod ="handle2",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "20000"),
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "1"),
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "90")
    })
    @GetMapping("/hytrix/ok/{id}")
    public String hytrixOk2(@PathVariable Integer id){
        System.out.println("执行开始--hytrixOk-3");
        if(id<0) {
            int i = 10 / 0;  //演示发生异常
        }
        //sleep();  //演示阻塞，卡顿
        System.out.println(Thread.currentThread().getName()+"--hytrixOk-2");
        System.out.println("执行结束--hytrixOk-2");
        return "ok";
    }


    private String handle(){
        System.out.println(Thread.currentThread().getName()+"--访问错误");
        return "error";
    }

    private String handle2(Integer id){
        System.out.println(Thread.currentThread().getName()+"--访问错误2"+new Date());
        return "error";
    }
}
